﻿using Microsoft.Extensions.Logging;
using ST.Common.Util.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace ST.Common.Util
{
	public class FileHelper
	{
		public static ILogger logger = LoggingHelper.CreateLogger<FileHelper>();

		/// <summary>
		/// 复制文件夹
		/// </summary>
		/// <param name="sourceDirName"></param>
		/// <param name="destDirName"></param>
		/// <param name="copySubDirs"></param>
		/// <param name="overwrite"></param>
		public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs, bool overwrite)
		{
			try
			{
				// Get the subdirectories for the specified directory.
				DirectoryInfo dir = new DirectoryInfo(sourceDirName);

				if (!dir.Exists)
				{
					return;
				}

				// If the destination directory doesn't exist, create it.
				if (!Directory.Exists(destDirName))
				{
					Directory.CreateDirectory(destDirName);
				}

				// Get the files in the directory and copy them to the new location.
				FileInfo[] files = dir.GetFiles();
				foreach (FileInfo file in files)
				{
					file.CopyTo(Path.Combine(destDirName, file.Name), overwrite);
				}

				// If copying subdirectories, copy them and their contents to new location.
				if (copySubDirs)
				{
					DirectoryInfo[] dirs = dir.GetDirectories();
					foreach (DirectoryInfo subdir in dirs)
					{
						DirectoryCopy(subdir.FullName, Path.Combine(destDirName, subdir.Name), copySubDirs, overwrite);
					}
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.Message);
			}
		}

		public static void DirectoryCopy(string sourceDirName, string destDirName, bool overwrite)
		{
			DirectoryCopy(sourceDirName, destDirName, true, overwrite);
		}

		public static void DirectoryCopy(string sourceDirName, string destDirName)
		{
			DirectoryCopy(sourceDirName, destDirName, true, true);
		}

		/// <summary>
		/// 将指定目录下的所有子目录单独压缩成一个压缩文件
		/// </summary>
		public static bool CompressAllSubFolder(string folderPath)
		{
			try
			{
				string[] dirs = Directory.GetDirectories(folderPath);
				if (dirs != null && dirs.Length > 0)
				{
					foreach (string dir in dirs)
					{
						string dirName = dir.Substring(dir.LastIndexOf('\\') + 1);
						var dstFileName = Path.Combine(folderPath, dirName + ".7z");
						ProcessStartInfo psi = new ProcessStartInfo();
						psi.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7za.exe");
						psi.WindowStyle = ProcessWindowStyle.Hidden;
						if (File.Exists(dstFileName))//更新压缩包
						{
							psi.Arguments = "u -t7z \"" + dstFileName + "\" \"" + dir + "\\*\" -mx=9 -r";
						}
						else//生成压缩包
						{
							psi.Arguments = "a -t7z \"" + dstFileName + "\" \"" + dir + "\\*\" -mx=9 -r";
						}

						Process proc = Process.Start(psi);
						proc.WaitForExit();
						if (proc.ExitCode != 0)
						{
							throw new Exception("压缩文件夹" + dir + "出错，错误代码：" + proc.ExitCode);
						}
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.Message);
				return false;
			}
		}

		public static bool CompressFolder(string folderPath)
		{
			try
			{
				folderPath = folderPath.TrimEnd(new char[] { '\\', '/' });
				int idx = folderPath.LastIndexOf('\\');
				string dirName = folderPath.Substring(idx + 1);
				var dstFileName = Path.Combine(folderPath.Substring(0, idx), dirName + ".7z");
				ProcessStartInfo psi = new ProcessStartInfo();
				psi.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7za.exe");
				psi.WindowStyle = ProcessWindowStyle.Hidden;
				if (File.Exists(dstFileName))//更新压缩包
				{
					psi.Arguments = "u -t7z \"" + dstFileName + "\" \"" + folderPath + "\\*\" -mx=9 -r";
				}
				else//生成压缩包
				{
					psi.Arguments = "a -t7z \"" + dstFileName + "\" \"" + folderPath + "\\*\" -mx=9 -r";
				}

				Process proc = Process.Start(psi);
				proc.WaitForExit();
				if (proc.ExitCode != 0)
				{
					throw new Exception("压缩文件夹" + folderPath + "出错，错误代码：" + proc.ExitCode);
				}
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.Message);
				return false;
			}
		}

		public static bool ExtractsToFolderFromArchive(string archivePath, string extractPath, bool deleteFiles, bool createArchiveFolder)
		{
			try
			{
				string dstPath = extractPath;
				if (createArchiveFolder)
				{
					string archiveName = Path.GetFileNameWithoutExtension(archivePath);
					dstPath = Path.Combine(extractPath, archiveName);
				}
				if (deleteFiles)
				{
					Directory.Delete(dstPath, true);
				}
				ProcessStartInfo psi = new ProcessStartInfo();
				psi.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7za.exe");
				psi.WindowStyle = ProcessWindowStyle.Hidden;
				psi.UseShellExecute = false;
				psi.Arguments = "x \"" + archivePath + "\" -o\"" + dstPath + "\" -aoa";

				Process proc = Process.Start(psi);
				proc.WaitForExit();
				if (proc.ExitCode != 0)
				{
					throw new Exception("解压缩文件" + archivePath + "出错，错误代码：" + proc.ExitCode);
				}
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.Message);
				return false;
			}
		}

		/// <summary>
		/// 功能类似于“解压到当前文件夹”
		/// </summary>
		/// <param name="archivePath"></param>
		/// <param name="extractPath"></param>
		/// <returns></returns>
		public static bool ExtractsToFolderFromArchive(string archivePath, string extractPath)
		{
			return ExtractsToFolderFromArchive(archivePath, extractPath, true, false);
		}

		public static bool ExtractsAllToFolder(string archiveFolderPath, string extractPath, string fileExtension, bool deleteFiles, bool createArchiveFolder)
		{
			try
			{
				if (deleteFiles)
				{
					if (createArchiveFolder)
					{
						string[] files = Directory.GetFiles(archiveFolderPath, "*." + fileExtension);
						if (files != null && files.Length > 0)
						{
							foreach (string file in files)
							{
								string archiveName = Path.GetFileNameWithoutExtension(file);
								string dstPath = Path.Combine(extractPath, archiveName);
								Directory.Delete(dstPath, true);
							}
						}
					}
					else
					{
						Directory.Delete(extractPath, true);
					}
				}

				ProcessStartInfo psi = new ProcessStartInfo();
				psi.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7za.exe");
				psi.WindowStyle = ProcessWindowStyle.Hidden;
				if (createArchiveFolder)
				{
					psi.Arguments = "x \"" + archiveFolderPath + "\\*." + fileExtension + "\" -o\"" + extractPath + "\\*\" -aoa";
				}
				else
				{
					psi.Arguments = "x \"" + archiveFolderPath + "\\*." + fileExtension + "\" -o\"" + extractPath + "\" -aoa";
				}

				Process proc = Process.Start(psi);
				proc.WaitForExit();
				if (proc.ExitCode != 0)
				{
					throw new Exception("解压缩文件夹" + archiveFolderPath + "出错，错误代码：" + proc.ExitCode);
				}
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.Message);
				return false;
			}
		}

		/// <summary>
		/// 功能类似于“解压到当前文件夹”
		/// </summary>
		/// <param name="archivePath"></param>
		/// <param name="extractPath"></param>
		/// <returns></returns>
		public static bool ExtractsAllToFolder(string archiveFolderPath, string extractPath, string fileExtension)
		{
			return ExtractsAllToFolder(archiveFolderPath, extractPath, fileExtension, false, false);
		}

		/// <summary>
		/// 解压所有7z文件，功能类似于“解压到当前文件夹”
		/// </summary>
		/// <param name="archivePath"></param>
		/// <param name="extractPath"></param>
		/// <returns></returns>
		public static bool ExtractsAllToFolder(string archiveFolderPath, string extractPath)
		{
			return ExtractsAllToFolder(archiveFolderPath, extractPath, "7z", false, false);
		}
	}
}
